<script context="module">
	export function preload({params}) {
		return this.fetch(`${params.name}.json`).then(r => r.json()).then(({name, collection, error}) => {
			return { name, collection };
		});
	}
</script>

<script>
	import { onMount } from "svelte";
	import capitalize from "capitalize";

	import Page from "../components/Page.svelte";
	import Selector from "../components/Selector.svelte";
	
	export let name;
	export let collection;

	/** @type {import("../rust/namegen-wasm").default} */
	let generator = null;
	let selectedSuffix = "";
	let selectedFormat = "";
	let generatedFormat = "";
	let generatedSuffix = "";
	let result = ""
	let failed = false;
	let buffer = [];
	let formats = [];
	let suffixes = [];
	
	let loaded = "";
	let mounted = false;

	function reload() {
		loaded = name.name;

		import("../rust/namegen-wasm").then(({load, default: NameGenerator}) => {
			return load().then(() => {
				console.log("Setting up", name.name);
				generator = new NameGenerator(name.data);
			})
		}).catch(() => {
			failed = true;
		}).finally(() => {
			loaded = name.name;
		})
	}

	function generate() {
		if (loaded !== name.name) {
			return;
		}

		let format = `${selectedFormat}:${selectedSuffix}`;
		if (!name.data.formats.find(f => f.name === format)) {
			format = selectedFormat;
		}
		if (!name.data.formats.find(f => f.name === format)) {
			return;
		}

		if (generator !== null) {
			if (buffer.length === 0) {
				console.time("Generate 64 names");
				buffer = generator.generateMany(format, 64);
				console.timeEnd("Generate 64 names");
			}
			
			result = buffer.pop();
		} else {
			result = name.examples[format][Math.floor(Math.random() * name.examples[format].length)]
		}

		generatedFormat = selectedFormat;
		generatedSuffix = selectedSuffix;
	}

	onMount(() => {
		mounted = true;
	})

	$: {
		if (mounted && loaded !== name.name) {
			generator = null;
			buffer = [];
			generatedFormat = "";
			generatedSuffix = "";
			selectedFormat = "";
			selectedSuffix = "";
			reload();
		}
	}

	$: {
		if (mounted && (selectedFormat !== generatedFormat || selectedSuffix !== generatedSuffix)) {
			buffer = [];
			generate();
		}
	}

	$: {
		const formatNames = name.data.formats.map(f => f.name.split(":")[0]).filter((f, i, a) => !a.slice(0, i).includes(f));
		const suffixNames = name.data.formats.map(s => s.name.split(":")[1]).filter(s => s).filter((s, i, a) => !a.slice(0, i).includes(s));
		const formatLabels = formatNames.map(n => name.metadata[`formatLabel_${n}`] || n.split("_").map(t => capitalize(t)).join(" "));
		const suffixLabels = suffixNames.map(n => name.metadata[`formatSuffixLabel_${n}`] || n.split("_").map(t => capitalize(t)).join(" "));
	
		formats = formatNames.map((n, i) => ({value: n, text: formatLabels[i]}));
		suffixes = suffixNames.map((n, i) => ({value: n, text: suffixLabels[i]}));
	}
</script>

<svelte:head>
	<title>{name.metadata.name} - Namegen 5</title>
</svelte:head>
<Page collection={collection} selected={name.name}>
	<div class="name">
		<h1>{name.metadata.name}</h1>
		<div class="cateogry">{name.metadata.category}</div>
		<div class="description">{name.metadata.description || ""}</div>
		<div style="color: {name.metadata.color || "#eeeeee"}" class:long={result.length > 25} class="result">{result}</div>
		{#if (failed)}
			<div class="failed">Your browser does not support Webassembly, the generator will only pick one out of 30 examples.</div>
		{/if}
		{#if suffixes.length > 0}
			<Selector color={name.metadata.color} bgcolor={name.metadata.bgcolor} label={name.metadata.formatSuffixType} options={suffixes} bind:value={selectedSuffix} />
		{/if}
		<Selector color={name.metadata.color} bgcolor={name.metadata.bgcolor} label="Format" prefer="full_" options={formats} bind:value={selectedFormat} />

		<button disabled={(loaded !== name.name) && !failed} on:click={generate}>Generate</button>
		<div class="footnote">{name.metadata.footnote || ""}</div>
	</div>
</Page>

<style>
	h1 {
		text-align: center;
		margin-bottom: 0;
		line-height: 1em;
	}

	div.failed {
		color: #fc1;
		font-size: 0.9em;
	}

	div.footnote {
		font-size: 0.9em;
		color: #555;
		margin-top: 2em;
	}
	div.footnote:empty {
		display: none;
	}

	div.cateogry {
		font-size: 0.75em;
		opacity: 0.75;
		margin-bottom: 1em;
	}

	div.result {
		border: 1px solid #000;
		border-radius: 0.5em;
		background-color: #333;
		padding: 0.5em 0;
		color: #eee;
		text-align: center;
		font-size: 1.5em;
		min-height: 1.5em;
	}
	div.result.long {
		font-size: 1.25em;
		padding: 0.75em 0;

	}

	button {
		background: #333;
		outline: none;
		border: 1px solid #000;
		color: #ccc;
		padding: 0.25em 1ch;
		margin: 1.5em 0 0.5em 0;
		font-size: 1.5em;
	}
	button:hover {
		color: #fff;
	}
	button:active {
		background: #444;
	}
</style>
